/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver.
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#ifndef UHM_MESH_NODE_HXX
#define UHM_MESH_NODE_HXX

namespace uhm {
  typedef class Node_*    Node;
  typedef class Element_* Element;
  typedef class Mesh_*    Mesh;

  bool node_valid(Node n);

  // ----------------------------------------------------------------
  // ** Node class
  class Node_ : public Object_< std::pair <int,int> > {
  protected:
    // store nodal connectivity according to its generation
    std::set< Element > owner;

    // n_dof  - actual dof that the node has
    // p      - order from FE
    // kind   - boundary node and the others
    // offset - offset in assembled matrix, where this node places in mesh
    int n_dof, p, kind, offset;
    int marker;

    void _init(std::pair<int,int> id, int n_dof, int p,int kind);

  public:
    Node_();
    Node_(std::pair<int,int> id);
    Node_(std::pair<int,int> id, int n_dof, int p, int kind);
    virtual ~Node_();
    virtual bool disp();
    virtual bool disp(FILE *stream);

    bool operator<(const Node_ &b) const;

    void reset_owner();
   
    void set_kind   (int kind);
    void set_n_dof  (int n_dof);
    void set_p      (int p);
    void set_offset (int offset);
    void set_marker (int marker);
    
    int  get_kind();
    int  get_n_dof();
    int  get_p();
    int  get_n_owner();
    int  get_offset();
    int  get_marker();

    bool is_owned_by  (Element e);
    bool is_same_as   (Node n);

    void add_owner    (Element e);
    void remove_owner (Element e);

    void clean_connectivity();

    friend class Mesh_;
    friend bool build_graph(std::vector< Element > *orphan,
			     Element parent,
			     //                                
			     std::vector< int > *xadj,
			     std::vector< int > *adjncy,
			     std::vector< int > *adjwgt);
    friend bool build_tree_var_1(Mesh m);

    friend bool node_valid(Node n);
  };
  // ----------------------------------------------------------------
  // ** Definition
  inline void Node_::_init(std::pair<int,int> id, int n_dof, int p,int kind) {
    this->cookie = UHM_NODE_COOKIE;
    this->id = id;
    this->n_dof = n_dof;
    this->p = p;
    this->kind = kind;
    this->offset = 0;
    this->marker = -1;
  }
  inline bool Node_::operator<(const Node_ &b) const { 
    return (this->id < b.id); 
  }
  inline bool node_valid(Node n) {
    return (n && n->cookie == UHM_NODE_COOKIE); 
  }
}

#endif
